/**
*Createed by yellowTT's game
*FileName:     AutoGetUIComponentPath.cs
*Author:       yellowTT
*UnityVersion：5.6.0f3
*Date:         2018年12月18日,Tuesday, 17时39分08秒
*/

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;

public class AutoGetUIComponentPath : Editor
{
    static Dictionary<string, string> comName_prefix = new Dictionary<string, string>
    {
        {"Text","txt_" },
        {"Image","img_" },
        {"Slider","slider_" },
        {"GameObject","obj_" },
        { "Toggle","tog_" },
        {"Transform","trans_"},
        {"RectTransform","rectTrans_"},
        {"Button","btn_"},
    };


    //% CTRL 在Windows / CMD在OSX
    //# Shift
    //& Alt
    //LEFT/RIGHT/UP/DOWN-光标键
    //F1…F12
    //HOME, END, PGUP, PDDN
    //字母键不是key-sequence的一部分，要让字母键被添加到key-sequence中必须在前面加上下划线（例如：_g对应于快捷键”G”）
    [MenuItem("Tools/自动生成选中对象的所有子部件的Find路径代码,可多选(整个的UI的直接父对象为MainCanvas) &q")]
    public static void Run()
    {
        //声明字段的字符串
        string fieldList = "";
        //Find路径的字符串
        string findList = "";

        Object[] objs = Selection.GetFiltered(typeof(Object), SelectionMode.Unfiltered);
        for (int i = 0; i < objs.Length; i++) {
            findList += AssembleStr(objs[i] as GameObject,ref fieldList);
        }
        //复制到剪贴板
        TextEditor textEditor = new TextEditor();
        textEditor.text = fieldList + "\n".Replace("\\n", "\n") + findList;
        textEditor.OnFocus();
        textEditor.Copy();
    }

    static string AssembleStr(GameObject obj,ref string fieldList)
    {
        string path= GetRealPath(Recursion(obj));
        string comName = "";
        string prefix = "";
        string finalStr = "";
        //每个对象最多只能包含一个Graphic组件
        var graphicCom = obj.GetComponent<MaskableGraphic>();
        if (graphicCom != null) {
            comName = GetNameFromType(graphicCom.GetType().ToString());
            prefix = comName_prefix[comName];
            finalStr += GetFinalStr(prefix, obj.name, path, comName);
            fieldList += GetFinalFieldStr(comName, prefix, obj.name);
        }

        ////每个对象最多只能包含一个Selectable组件
        var selectCom = obj.GetComponent<Selectable>();
        if (selectCom != null)
        {
            comName = GetNameFromType(selectCom.GetType().ToString());
            prefix = comName_prefix[comName];
            finalStr += GetFinalStr(prefix, obj.name, path, comName);
            fieldList += GetFinalFieldStr(comName, prefix, obj.name);
        }

        var rectTrans= obj.GetComponent<RectTransform>();
        if (graphicCom == null && selectCom == null&&rectTrans != null) {
            comName = GetNameFromType(rectTrans.GetType().ToString());
            prefix = comName_prefix[comName];
            finalStr += GetFinalStr(prefix, obj.name, path, comName);
            fieldList += GetFinalFieldStr(comName, prefix, obj.name);
        }

        //没有挂任何所需组件，则声明gameObject
        if (graphicCom == null && selectCom == null) {
            finalStr += comName_prefix["GameObject"] + obj.name + "=transform.Find(\"" + path + "\").gameObject;\n".Replace("\\n", "\n");
            fieldList += GetFinalFieldStr("GameObject", comName_prefix["GameObject"], obj.name);
        }

        return finalStr;
    }

    /// <summary>
    /// 根据组件的类型名获取所挂载的具体组件名
    /// </summary>
    /// <param name="typeName"></param>
    /// <returns></returns>
    static string GetNameFromType(string typeName) {
        return typeName.Substring(typeName.LastIndexOf('.') + 1);
    }

    /// <summary>
    /// 从根对象开始递归获取对象的层级路径
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    static string Recursion(GameObject obj)
    {
        string str = "/" + obj.name;
        if (obj.transform.parent != null)
        {
            str = Recursion(obj.transform.parent.gameObject) + str;
        }
        return str;
    }

    /// <summary>
    /// 组装查找语句
    /// </summary>
    /// <param name="prefix"></param>
    /// <param name="objName"></param>
    /// <param name="path"></param>
    /// <param name="component"></param>
    /// <returns></returns>
    static string GetFinalStr(string prefix,string objName,string path,string component) {
        return prefix + objName+ "=transform.Find(\"" + path + "\").GetComponent<"+ component + ">();\n".Replace("\\n", "\n");
    }

    static string UpperFirstChar(string str)
    {
        return str.Substring(0, 1).ToUpper() + str.Substring(1, str.Length - 1);
    }

    /// <summary>
    /// 组装字段语句
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    static string GetFinalFieldStr(string fieldType,string prefix,string objName) {
        return "public"+" "+ fieldType+" " + prefix + objName+ ";\n".Replace("\\n", "\n");
    }

    /// <summary>
    /// 将层级路径换成Find所要查找的路径
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    static string GetRealPath(string path) {
        //           /MainCanvas/BattleInfoView/monsterInfos/monsterInfo
        int count = 1;
        while (count <= 3) {
            path = path.Substring(path.IndexOf('/') + 1);
            count++;
        }
        return path;
    }
}
